package com.unitd.base.module.consumer.comm.controller;

import com.alibaba.fastjson.JSONObject;
import com.unitd.base.frame.plugin.module.dto.ResponseUtils;
import com.unitd.base.module.consumer.comm.interceptor.AuthorizationInterceptor;
import com.unitd.base.module.master.pojo.dto.UserVO;
import com.unitd.base.module.master.service.TokenService;
import com.unitd.base.module.master.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.TypeMismatchException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.WebRequest;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Map;


/**
 * 前端接口基础控制类
 *
 * @author hudan
 * @version 1.0
 * @filename ApiBaseAction.java
 * @copyright www.unitd.com
 * @date 2020-07-01
 */
@Slf4j
public class ApiBaseAction {

    @Autowired
    protected HttpServletRequest request;
    @Autowired
    protected TokenService apiTokenService;
    @Autowired
    protected UserService userService;

    /**
     * initBinder 初始化绑定 <br>
     * 这里处理了3种类型<br>
     * 1、字符串自动 trim 去掉前后空格 <br>
     * 2、java.util.Date 转换为 "yyyy-MM-dd HH:mm:ss" 格式<br>
     * 3、java.sql.Date 转换为 "yyyy-MM-dd" 格式<br>
     * 4、java.util.Timestamps 时间转换
     *
     * @param binder  WebDataBinder 要注册的binder
     * @param request 前端请求
     */
    @InitBinder
    public void initBinder(WebDataBinder binder, WebRequest request) {
        // 字符串自动Trim
        binder.registerCustomEditor(String.class, new StringTrimmerEditor(false));
    }

    /**
     * 处理参数绑定异常
     *
     * @param e 参数绑定异常
     * @return 反馈绑定异常处理结果
     */
    @ExceptionHandler({BindException.class, MissingServletRequestParameterException.class, TypeMismatchException.class})
    @ResponseBody
    public Map<String, Object> bindException(Exception e) {
        if (e instanceof BindException) {
            return ResponseUtils.toResponsObject(1, "参数绑定异常", e.getMessage());
        }
        return ResponseUtils.toResponsObject(1, "处理异常", e.getMessage());
    }

    /**
     * 获取当前发起请求的客户端IP
     *
     * @return 客户端IP
     */
    public String getClientIp() {
        String xff = request.getHeader("X-Real-IP");
        if (xff != null) {
            return xff;
        }
        xff = request.getHeader("x-forwarded-for");
        if (xff == null) {
            return "8.8.8.8";
        }
        return xff;
    }

    /**
     * 获取当前发起请求的json对象
     *
     * @return 请求的json对象
     */
    public JSONObject getJsonRequest() {
        JSONObject result = null;
        StringBuilder sb = new StringBuilder();
        try {
            BufferedReader reader = request.getReader();
            char[] buff = new char[1024];
            int len;
            while ((len = reader.read(buff)) != -1) {
                sb.append(buff, 0, len);
            }
            result = JSONObject.parseObject(sb.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }

        return result;
    }

    /**
     * 获取请求的用户Id
     *
     * @return 客户端Ip
     */
    public Long getUserId() {
        String token = request.getHeader(AuthorizationInterceptor.LOGIN_TOKEN_KEY);
        // 查询token信息
        return apiTokenService.getUserIdByToken(token);
    }

    /**
     * 获取请求的用户Id
     *
     * @return 客户端Ip
     */
    public String getUserDefDbName() {
        Long userId = getUserId();
        UserVO user = userService.selectById(userId);
        // 查询token信息
        return user.getCompanyDatasource().getDbName();
    }
}